package moodish.comm;

import static org.junit.Assert.*;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import moodish.comm.ClientSideMessage.Type;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ServerCommunicationTest {

	private ServerCommunication server;
	private DealWithClient dwc;
	private Socket socket;
	private ObjectOutputStream out;
	private static final int PORTO = 9090;

	@Before
	public void setUp() throws Exception {
		server = new ServerCommunication();
		dwc = new DealWithClient(socket, server);
	}

	@After
	public void tearDown() throws Exception {
		server = null;
		dwc.interrupt();
		out = null;
		socket = null;
	}

	@Test
	public void testStart() {
		server.start();
		assertEquals(PORTO, ServerCommunication.PORTO);
	}

	@Test
	public void testGetNextMessage() {
		assertFalse(server.hasNextMessage());
		assertEquals(null, server.getNextMessage());
		ServerSide message = new ServerSide(null, null, null);
		server.AddMessage(message);
		assertEquals(message, server.getNextMessage());
	}

	@Test
	public void testHasNextMessage() {
		assertFalse(server.hasNextMessage());
		server.AddMessage(new ServerSide(null, null, null));
		assertTrue(server.hasNextMessage());

	}

	@Test
	public void testSendMoodishMessage() throws IOException {
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo19", out, dwc);
		assertTrue(server.clientIsConnected("Grupo19"));
		server.sendMoodishMessage("Grupo19", "Grupo16", "Good");
	}

	@Test
	public void testSendNewFriendship() throws IOException {
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo19", out, dwc);
		assertTrue(server.clientIsConnected("Grupo19"));
		server.sendNewFriendship("Grupo16", "Grupo19");
	}

	@Test
	public void testSendNewUnfriendship() throws IOException {
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo19", out, dwc);
		assertTrue(server.clientIsConnected("Grupo19"));
		server.sendNewUnfriendship("Grupo16", "Grupo19");
	}

	@Test
	public void testSendError() throws UnknownHostException, IOException {
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.sendError("Grupo16", "Error");
	}

	@Test
	public void testSendClientConnected() throws IOException {
		assertFalse(server.clientIsConnected("Grupo16"));
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.sendClientConnected("Grupo16", "Grupo19");
	}

	@Test
	public void testSendClientDisconnected() throws IOException {
		server.start();
		socket = new Socket("localhost", 9090);
		assertEquals(PORTO, ServerCommunication.PORTO);
		out = new ObjectOutputStream(socket.getOutputStream());
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo19", out, dwc);
		assertTrue(server.clientIsConnected("Grupo19"));
		server.disconnectClient("Grupo19");
		assertFalse(server.clientIsConnected("Grupo19"));
		server.sendClientDisconnected("Grupo16", "Grupo19");
	}

	@Test
	public void testClientIsConnected() {
		assertFalse(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
	}

	@Test
	public void testDisconnectClient() {
		assertFalse(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
		server.disconnectClient("Grupo16");
		assertFalse(server.clientIsConnected("Grupo16"));
	}

	@Test
	public void testAddOuts() {
		assertFalse(server.clientIsConnected("Grupo16"));
		server.AddOuts("Grupo16", out, dwc);
		assertTrue(server.clientIsConnected("Grupo16"));
	}

	@Test
	public void testAddMessage() {
		assertFalse(server.hasNextMessage());
		server.AddMessage(new ServerSide(null, null, null));
		assertTrue(server.hasNextMessage());
	}

}
